package com.byd.modules.biz.service.impl;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchPhraseQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.nested.Nested;
import org.elasticsearch.search.aggregations.bucket.nested.NestedAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms.Bucket;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.byd.config.ElasticsearchConfig;
import com.byd.modules.biz.entity.CarModelEntity;
import com.byd.modules.biz.entity.SuperviseEntity;
import com.byd.modules.biz.entity.SuperviseREntity;
import com.byd.modules.biz.entity.SuperviseSubEntity;
import com.byd.modules.biz.service.CarModelService;
import com.byd.modules.biz.service.DashboardService;
import com.google.gson.Gson;

@Service
public class DashboardServiceImpl implements DashboardService {
    Logger logger = Logger.getLogger(DashboardServiceImpl.class);
    
    @Autowired
    private CarModelService carModelService;
    
    @Autowired
    ElasticsearchConfig elasticsearchConfig;
    String json = null;


    public static void main(String[] args) throws UnknownHostException {
        // on startup AWCgQG4m1caaXKmn3fbu
        Settings settings = Settings.builder().put("cluster.name", "biyadi-test").build();
        // Add transport addresses and do something with the client...
        TransportClient client = new PreBuiltTransportClient(settings).addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("101.89.68.208"), 9300));
        // GetResponse response = client.prepareGet("byd", "article",
        // "AWCgQG4m1caaXKmn3fbu").setOperationThreaded(false).get();// 线程安全
        // 按照时间分类
        
     /*     SearchResponse searchResponse = client.prepareSearch("byd").setTypes("article")
          .setQuery(QueryBuilders.matchAllQuery())
          .setSearchType(SearchType.QUERY_THEN_FETCH)
          .addAggregation(AggregationBuilders.terms("group_bbs")
          .field("emotion.keyword").size(10))//根据age分组，默认返回10，size(0)也是10
          .get();
          
          Terms terms = searchResponse.getAggregations().get("group_bbs");
          List<Bucket> buckets = (List<Bucket>) terms.getBuckets();
          for(Bucket bt : buckets)
          {
          System.out.println(bt.getKey() + " " + bt.getDocCount());
          }*/
         

       // DashboardServiceImpl.dataHistogramAggregation();

        /*
         * System.out.println(response.getSourceAsString());
         * 
         * 
         * ValueCountAggregationBuilder field = AggregationBuilders
         * .count("agg")
         * .field("height");
         */

        /*
         * SearchResponse scrollResp = client.prepareSearch("byd").addSort(FieldSortBuilder.DOC_FIELD_NAME,
         * SortOrder.ASC)
         * // .setScroll(new TimeValue(60000))
         * .setFrom(1).setSize(10).get(); // max of 100 hits will be returned for each scroll
         * // Scroll until no hits are returned
         * for (SearchHit hit : scrollResp.getHits().getHits()) {
         * // Handle the hit...
         * System.out.println(hit.getSourceAsString());
         * }
         */

        // on shutdown

        // client.close();

//        MatchPhraseQueryBuilder mpq1 = QueryBuilders.matchPhraseQuery("bbs_name", "博越");
//        // WildcardQueryBuilder mpq3 = QueryBuilders.wildcardQuery("brand.keyword", "*");
//        RangeQueryBuilder mpq2 = QueryBuilders.rangeQuery("post_time.keyword").gte("2017-08-01");
//        QueryBuilder qb = QueryBuilders.boolQuery().must(mpq1).must(mpq2).must(QueryBuilders.existsQuery("result"));
//
//        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//        sourceBuilder.query(qb);
//
//        SearchResponse scrollResp = client.prepareSearch("byd")
//                // .setQuery(QueryBuilders.rangeQuery("post_time.keyword").gte("2016-01-01"))
//                .setQuery(qb).get();
//
//        System.out.println(scrollResp.getHits().totalHits);
        
       DashboardServiceImpl d = new DashboardServiceImpl();
//        
        d.queryList1("2017-11-28", "2018-01-26", "全部");
    }
    
    

    /**
     * 重载方法
     * 
     * @param params
     * @return
     */
    @Override
    public List<SuperviseEntity> queryList(Map<String, Object> params) {
        return null;
    }

    /**
     * 重载方法
     * 
     * @param id
     * @return
     */
    @Override
    public SuperviseEntity queryObject(String id) {
        SuperviseEntity res = null;
        try {
            Client client = elasticsearchConfig.getESClient();
            GetResponse response = client.prepareGet(elasticsearchConfig.getIndex(), "article", id).setOperationThreaded(false).get();// 线程安全
            // GetResponse response = client.prepareGet("byd", "article",
            // "AWCgQG4m1caaXKmn3fbu").setOperationThreaded(false).get();// 线程安全
            Gson g = new Gson();
            res = g.fromJson(response.getSourceAsString(), SuperviseEntity.class);
            res.setId(res.getId());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return res;
    }

    /**
     * 重载方法
     * 
     * @param supervise
     */
    @Override
    public void update(SuperviseREntity supervise) {
        Client client = elasticsearchConfig.getESClient();
        SuperviseEntity entity = this.queryObject("AWCgXNep1caaXKmnIBok");
        SuperviseSubEntity sub = new SuperviseSubEntity();
        sub.setBrand("宝马");
        sub.setEmotion("正面");
        entity.getResult().add(sub);
        UpdateResponse response = client.prepareUpdate(elasticsearchConfig.getIndex(), "article", "AWCgXNep1caaXKmnIBok").setDoc(new Gson().toJson(entity, SuperviseEntity.class), XContentType.JSON).get();

    }
    
    public Map<String, Object> queryList1(String startTime, String endTime, String car) throws UnknownHostException {
        //  Client client = elasticsearchConfig.getESClient();
          Settings settings = Settings.builder().put("cluster.name", "biyadi-test").build();
          TransportClient client = new PreBuiltTransportClient(settings).addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("101.89.68.208"), 9300));

          MatchPhraseQueryBuilder mpq1 = QueryBuilders.matchPhraseQuery("car_series", car);
          // WildcardQueryBuilder mpq3 = QueryBuilders.wildcardQuery("brand.keyword", "*");
          RangeQueryBuilder mpq2 = QueryBuilders.rangeQuery("create_date").format("yyyy-MM-dd").from(startTime).to(endTime);
          QueryBuilder qb = QueryBuilders.boolQuery().must(mpq1).must(mpq2);
          SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
          sourceBuilder.query(qb);
          SearchResponse scrollResp = client.prepareSearch(elasticsearchConfig.getIndex()).setQuery(qb).get();
          long total = scrollResp.getHits().totalHits;
          if (!"全部".equals(car)) {
              qb = QueryBuilders.boolQuery().must(mpq1).must(mpq2).must(QueryBuilders.existsQuery("result"));
          }
          SearchResponse scrollResp1 = client.prepareSearch(elasticsearchConfig.getIndex()).setQuery(qb).get();
          long total1 = scrollResp1.getHits().totalHits;
          long total2 = total-total1;
          
          System.out.println(total+"-"+total1+"-"+total2);
          
          
          SearchResponse searchResponse = client.prepareSearch(elasticsearchConfig.getIndex()).setTypes("article")
          .setQuery(qb)
          .setSearchType(SearchType.QUERY_THEN_FETCH)
          .addAggregation(AggregationBuilders.terms("group_car_series")
          .field("emotion.keyword").size(5))//emotion，默认返回10，size(0)也是10
          .get();
          
          Terms terms = searchResponse.getAggregations().get("group_car_series");
          List<Bucket> buckets = (List<Bucket>) terms.getBuckets();
          for(Bucket bt : buckets)
          {
              System.out.println(bt.getKey() + " " + bt.getDocCount());
          }
          
          
          SearchResponse searchResponse2 = client.prepareSearch(elasticsearchConfig.getIndex()).setTypes("article")
          .setQuery(qb)
          .setSearchType(SearchType.QUERY_THEN_FETCH)
          .addAggregation(AggregationBuilders.terms("group_create_date")
          .format("yyyy-MM-dd")
          .minDocCount(0)
          .field("create_date"))//根据age分组，默认返回10，size(0)也是10
          .get();
          
          Terms terms2 = searchResponse2.getAggregations().get("group_create_date");
          List<org.elasticsearch.search.aggregations.bucket.terms.LongTerms.Bucket> buckets2 = (List<org.elasticsearch.search.aggregations.bucket.terms.LongTerms.Bucket>) terms2.getBuckets();
          for(org.elasticsearch.search.aggregations.bucket.terms.LongTerms.Bucket bt : buckets2)
          {
              System.out.println(bt.getKeyAsString() + " " + bt.getDocCount());
          }
       
          

          return null;
      }

    /**
     * 重载方法
     * 
     * @param startTime
     * @param endTime
     * @param car
     * @return
     * @throws UnknownHostException 
     */
    @Override
    public Map<String, Object> queryList(String startTime, String endTime, String car1, String car2) {
        
        Map<String, Object> res = new HashMap<String, Object>();
        
        Client client = elasticsearchConfig.getESClient();
        
        BoolQueryBuilder qb = QueryBuilders.boolQuery();
        
        MatchPhraseQueryBuilder mpq1=null;
        if (StringUtils.isNotBlank(car1)&&!car1.equals("全部")) {
            if (StringUtils.isNotBlank(car2)&&!"全部".equals(car2)) {
       		 mpq1 = QueryBuilders.matchPhraseQuery("car_series", car2);
       	 }
       	 else
       	 {
             CarModelEntity carModel = carModelService.queryObject(Long.parseLong(car1));
             if(carModel!=null)
             {
            	 mpq1 = QueryBuilders.matchPhraseQuery("car_series", carModel.getName()); 
             }
       	 }
       	 qb.must(mpq1);
		}
        //RangeQueryBuilder mpq2 = QueryBuilders.rangeQuery("create_date").gte(startTime).lte(endTime);
        RangeQueryBuilder mpq2 = QueryBuilders.rangeQuery("post_time_new").gte(startTime).lte(endTime);
        if (StringUtils.isNotBlank(startTime)&&StringUtils.isNotBlank(endTime)) {
            qb.must(mpq2);
		}
        
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(qb);
        SearchResponse scrollResp = client.prepareSearch(elasticsearchConfig.getIndex()).setQuery(qb).get();
        long total = scrollResp.getHits().totalHits;
        
        if (mpq1!=null) {
//            qb = QueryBuilders.boolQuery().must(mpq1).must(mpq2).must(QueryBuilders.existsQuery("result"));
            qb = QueryBuilders.boolQuery().must(mpq1).must(mpq2).must(QueryBuilders.matchPhraseQuery("flag", "1"));
        }else{
//            qb = QueryBuilders.boolQuery().must(mpq2).must(QueryBuilders.existsQuery("result"));
            qb = QueryBuilders.boolQuery().must(mpq2).must(QueryBuilders.matchPhraseQuery("flag", "1"));
        }
        SearchResponse scrollResp1 = client.prepareSearch(elasticsearchConfig.getIndex()).setQuery(qb).get();
        long total1 = scrollResp1.getHits().totalHits;
        long total2 = total-total1;
        
        res.put("total", total);
        res.put("total1", total1);
        res.put("total2", total2);
        //System.out.println(total+"-"+total1+"-"+total2);
        
        
        NestedAggregationBuilder aggregation = AggregationBuilders.nested("group_result", "result")
        		.subAggregation(AggregationBuilders.terms("group_car_series")
        		.field("result.emotion.keyword").size(10));
        
        SearchResponse searchResponse = client.prepareSearch(elasticsearchConfig.getIndex()).setTypes("article")
                .setQuery(qb)
                .setSearchType(SearchType.QUERY_THEN_FETCH)
                .addAggregation(aggregation)//emotion，默认返回10，size(0)也是10
                .get();
//        SearchResponse searchResponse = client.prepareSearch(elasticsearchConfig.getIndex()).setTypes("article")
//        .setQuery(qb)
//        .setSearchType(SearchType.QUERY_THEN_FETCH)
//        .addAggregation(AggregationBuilders.terms("group_car_series")
//        .field("result.emotion.keyword").size(10))//emotion，默认返回10，size(0)也是10
//        .get();
        Nested agg = searchResponse.getAggregations().get("group_result");
        Terms terms = agg.getAggregations().get("group_car_series");
        
        //Terms terms = searchResponse.getAggregations().get("group_car_series");
        //List<Bucket> buckets = (List<Bucket>) terms.getBuckets();
        Map<Object, Long> ressub1 = new HashMap<Object, Long>();
        for (Terms.Bucket bucket : terms.getBuckets()) {
        	 ressub1.put(bucket.getKey(), bucket.getDocCount());
        	 System.out.println(bucket.getKey() + " " + bucket.getDocCount());
       }
//        for(Bucket bt : buckets)
//        {
//        	
//            ressub1.put(bt.getKey(), bt.getDocCount());
//            
//           //System.out.println(bt.getKey() + " " + bt.getDocCount());
//        }
        res.put("pie", ressub1);
        
        SearchResponse searchResponse2 = client.prepareSearch(elasticsearchConfig.getIndex()).setTypes("article")
        .addSort("post_time_new", SortOrder.ASC)
        .setQuery(qb)
        .setSearchType(SearchType.QUERY_THEN_FETCH)
        .addAggregation(AggregationBuilders.terms("group_post_time_new")
        .format("yyyy-MM-dd")
        .minDocCount(0)
        .field("post_time_new").size(differentDaysByMillisecond(startTime,endTime)))//根据age分组，默认返回10，size(0)也是10
        .get();
        
        Terms terms2 = searchResponse2.getAggregations().get("group_post_time_new");
        List<org.elasticsearch.search.aggregations.bucket.terms.LongTerms.Bucket> buckets2 = (List<org.elasticsearch.search.aggregations.bucket.terms.LongTerms.Bucket>) terms2.getBuckets();
//        Map<Object, Long> ressub2 = new HashMap<Object, Long>();
        TreeMap<Object, Long> ressub2 = new TreeMap<Object, Long>();
        for(org.elasticsearch.search.aggregations.bucket.terms.LongTerms.Bucket bt : buckets2)
        {
           // System.out.println(bt.getKey() + " " + bt.getDocCount());
            ressub2.put(bt.getKeyAsString(), bt.getDocCount());
        }
        res.put("line", ressub2);
        
        return res;
    }
    
    
    public static int differentDaysByMillisecond(String date1,String date2){
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        int days=30;
        try {
            days = (int) ((format.parse(date2).getTime() - format.parse(date1).getTime()) / (1000*3600*24));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return days;
    }
  

}